package com.ruoyi.redisLock;

import com.alibaba.fastjson2.JSONObject;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.redis.RedisCache;
import com.ruoyi.common.redis.RedisLock;
import com.ruoyi.common.sdk.sms.api.ISmsGateWayApi;
import com.ruoyi.common.sdk.sms.vo.request.SendMsgRequest;
import com.ruoyi.common.sdk.sms.vo.respone.SendMsgRespone;
import kotlin.jvm.Synchronized;
import lombok.extern.slf4j.Slf4j;
import org.apache.poi.ss.formula.functions.T;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Async;
import org.springframework.util.CollectionUtils;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.TimeUnit;

/**
 * @author ruoyi
 */
@Slf4j
@RestController
@RequestMapping("/redisLock")
public class RedisLockController {

    @Autowired
    private RedisLock redisLock;
    @Autowired
    private RedisCache redisCache;
    private final static String testList = "testList";
    private final static String lockKey = "lockKey_test";
    private final static String num = "num";

    @PostMapping("/testLock")
    synchronized
    public AjaxResult testLock() {
        // 获取分布式锁
        RLock lock = redisLock.getRLock("myLock");
        try {
            // 尝试加锁，最多等待10秒，锁的持有时间默认为30秒
            //此处没有设置leaseTime，会自动启动看门狗机制
            boolean isLocked = lock.tryLock(1, TimeUnit.SECONDS);
            if (isLocked) {
                // 成功获取到锁
                log.debug("线程:" + Thread.currentThread().getName() + "获得了锁");

                // 执行需要加锁的代码逻辑
                if (null != redisCache.getCacheObject(num)) {
                    Integer numValue = redisCache.getCacheObject(num);
                    redisCache.setCacheObject(num, ++numValue);
                    log.info("成功一次" + numValue);
                    Thread.sleep(10000);
                } else {
                    redisCache.setCacheObject(num, 0);
                    log.info("第一次成功");
                }
            } else {
                log.debug("获取锁失败");
                // 获取锁失败
                // 处理获取锁失败的逻辑
                // ...
            }
        } catch (InterruptedException e) {
            // 处理中断异常
            log.error(e.getMessage(), e);
        } finally {
            // 释放锁
            if(lock.isLocked() && lock.isHeldByCurrentThread()){
                lock.unlock();
                log.debug("释放锁成功");
            }
        }
        return AjaxResult.success();
    }
    /**
     * <pre>
     * 加锁
     * </pre>
     */
    @PostMapping("/redisLock")
    synchronized
    public AjaxResult redisLock(@RequestBody JSONObject json) {
        String lockKey = json.getString("lockKey");
        try {
            if (redisLock.tryLock(lockKey, 1)) {
                log.info("加锁成功");
                if (null != redisCache.getCacheObject(num)) {
                    Integer numValue = redisCache.getCacheObject(num);
                    redisCache.setCacheObject(num, ++numValue);
                    log.info("成功一次" + numValue);
                    Thread.sleep(2000);
                } else {
                    redisCache.setCacheObject(num, 0);
                    log.info("第一次成功");
                }
                return AjaxResult.success();
            } else {
                log.info("加锁失败");
                return AjaxResult.error();
            }
        } catch (Exception e) {
            e.printStackTrace();
            return AjaxResult.error(e.getMessage());
        }
//        finally {
//            redisLock.unlock(lockKey);
//            log.info("释放锁");
//        }
    }

    @PostMapping("/redisAdd")
    public AjaxResult redisAdd(@RequestBody JSONObject json) {
        try {
            if (null != redisCache.getCacheObject(num)) {
                Integer numValue = redisCache.getCacheObject(num);
                redisCache.setCacheObject(num, ++numValue);
                log.info("成功一次" + numValue);
                Thread.sleep(500);
            } else {
                redisCache.setCacheObject(num, 0);
                log.info("第一次成功");
            }
            return AjaxResult.success();
        } catch (Exception e) {
            e.printStackTrace();
            return AjaxResult.error(e.getMessage());
        }
    }

    @PostMapping("/lock")
    public AjaxResult lock() {
        try {
            return AjaxResult.success(redisLock.lock(lockKey));
        } catch (Exception e) {
            e.printStackTrace();
            return AjaxResult.error(e.getMessage());
        }
    }

    @PostMapping("/getRLock")
    public AjaxResult getRLock() {
        try {
            return AjaxResult.success(redisLock.getRLock(lockKey));
        } catch (Exception e) {
            e.printStackTrace();
            return AjaxResult.error(e.getMessage());
        }
    }

    @PostMapping("/unlock")
    public AjaxResult unlock() {
        try {
            redisLock.unlock(lockKey);
            return AjaxResult.success();
        } catch (Exception e) {
            e.printStackTrace();
            return AjaxResult.error(e.getMessage());
        }
    }

    @PostMapping("/tryLock")
    public AjaxResult tryLock() {
        try {
            return AjaxResult.success(redisLock.tryLock(lockKey, 1));
        } catch (Exception e) {
            e.printStackTrace();
            return AjaxResult.error(e.getMessage());
        }
    }

}
